<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'

export default {
  mixins: [resize],
  props: {
    className: { type: String, default: 'chart' },
    width: { type: String, default: '100%' },
    height: { type: String, default: '350px' },
    chartData: { type: Object, required: true },
    showType: { type: Boolean, default: false },
    title: { type: String, default: '' }
  },
  data() {
    return {
      chart: null,
      showChartData: { tradingDay: [], pnlToday: [], pnlHold: [], pnlTrade: [] },
      pnlAccuTotal: [],
      pnlAccuHold: [],
      pnlAccuTrade: []
    }
  },
  watch: {
    chartData: { deep: true, handler() { this.setOptions() } },
    showType: { deep: true, handler() { this.resetData() } }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el, 'macarons')
      this.setOptions(this.chartData)
      this.chart.on('datazoom', (param) => {
        const length = this.showChartData.gridTime.length
        const startIndex = Math.floor(param.start / 100 * length)
        const endIndex = Math.ceil(param.end / 100 * length)
        if (!this.showType) {
          if (length !== undefined && length > 0) {
            this.updateOptions(param.start, param.end, startIndex, endIndex)
          }
        } else {
          const rangeData = { gridTime: [], pnlToday: [], pnlHold: [], pnlTrade: [] }
          for (let m = startIndex; m <= endIndex; m++) {
            rangeData.gridTime.push(this.showChartData.gridTime[m])
            rangeData.pnlToday.push(this.showChartData.pnlToday[m])
            rangeData.pnlHold.push(this.showChartData.pnlHold[m])
            rangeData.pnlTrade.push(this.showChartData.pnlTrade[m])
          }
          this.$emit('barChartRangeChange', rangeData)
        }
      })
    },
    setOptions() {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData))
      if (this.showChartData.gridTime.length !== 0) {
        this.pnlAccuTotal[0] = this.showChartData.pnlToday[0]
        this.pnlAccuHold[0] = this.showChartData.pnlHold[0]
        this.pnlAccuTrade[0] = this.showChartData.pnlTrade[0]

        for (let i = 1; i < this.showChartData.gridTime.length; i++) {
          this.pnlAccuTotal[i] = this.showChartData.pnlToday[i] + this.pnlAccuTotal[i - 1]
          this.pnlAccuHold[i] = this.showChartData.pnlHold[i] + this.pnlAccuHold[i - 1]
          this.pnlAccuTrade[i] = this.showChartData.pnlTrade[i] + this.pnlAccuTrade[i - 1]
        }
      }

      this.chart.setOption({
        title: { left: 'left', text: this.title },
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }},
        grid: { left: '2%', right: '2%', bottom: '3%', containLabel: true },
        xAxis: [{ type: 'category', data: this.showChartData.gridTime, boundaryGap: true }],
        yAxis: [{ type: 'value', minInterval: 1, boundaryGap: [0, 0.1] }],
        legend: { left: 'right', data: ['pnlToday', 'pnlHold', 'pnlTrade'] },
        series: [
          { name: 'pnlToday', type: 'bar', data: this.showChartData.pnlToday },
          { name: 'pnlHold', type: 'bar', data: this.showChartData.pnlHold },
          { name: 'pnlTrade', type: 'bar', data: this.showChartData.pnlTrade }
        ],
        dataZoom: [
          { show: true, realtime: true, start: 0, end: 50 },
          { type: 'inside', realtime: true, start: 0, end: 50, zoomOnMouseWheel: false }
        ]
      })
      this.chart.dispatchAction({ type: 'dataZoom', start: 0, end: 50 })
    },
    resetData() {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData))
      this.chart.setOption({
        xAxis: [{ data: this.showChartData.gridTime }],
        series: [
          { data: this.showChartData.pnlToday },
          { data: this.showChartData.pnlHold },
          { data: this.showChartData.pnlTrade }
        ],
        dataZoom: [
          { show: true, realtime: true, start: 0, end: 50 },
          { type: 'inside', realtime: true, start: 0, end: 50 }
        ]
      })
      this.chart.dispatchAction({ type: 'dataZoom', start: 0, end: 50 })
    },
    updateOptions(startPos, endPos, startIndex, endIndex) {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData))
      const rangeData = { gridTime: [], pnlToday: [], pnlHold: [], pnlTrade: [] }

      for (let m = startIndex; m <= endIndex; m++) {
        if (startIndex === 0) {
          this.showChartData.pnlToday[m] = this.pnlAccuTotal[m]
          this.showChartData.pnlHold[m] = this.pnlAccuHold[m]
          this.showChartData.pnlTrade[m] = this.pnlAccuTrade[m]
        } else {
          this.showChartData.pnlToday[m] = this.pnlAccuTotal[m] - this.pnlAccuTotal[startIndex - 1]
          this.showChartData.pnlHold[m] = this.pnlAccuHold[m] - this.pnlAccuHold[startIndex - 1]
          this.showChartData.pnlTrade[m] = this.pnlAccuTrade[m] - this.pnlAccuTrade[startIndex - 1]
        }
        rangeData.gridTime.push(this.showChartData.gridTime[m])
        rangeData.pnlToday.push(this.showChartData.pnlToday[m])
        rangeData.pnlHold.push(this.showChartData.pnlHold[m])
        rangeData.pnlTrade.push(this.showChartData.pnlTrade[m])
      }

      this.chart.setOption({
        xAxis: [{ data: this.showChartData.gridTime }],
        series: [
          { data: this.showChartData.pnlToday },
          { data: this.showChartData.pnlHold },
          { data: this.showChartData.pnlTrade }
        ],
        dataZoom: [
          { show: true, realtime: true, start: startPos, end: endPos },
          { type: 'inside', realtime: true, start: startPos, end: endPos }
        ]
      })

      this.$emit('barChartRangeChange', rangeData)
    }
  }
}
</script>
